using System;
using System.ComponentModel;
using MvvmUtils.ViewModels;
using NUnit.Framework;

namespace MvvmUtils.Tests.ViewModels
{
    public static class ViewModelAssert
    {
        public static void RaisesPropertyChanged<TViewModel>(
            TViewModel viewModel,
            string propertyName,
            Action<TViewModel> method, 
            int expectedRaisesCount)
            where TViewModel : ViewModel
        {
            if (viewModel == null) throw new ArgumentNullException("viewModel");
            if (method == null) throw new ArgumentNullException("method");
            if(string.IsNullOrEmpty(propertyName)) throw new ArgumentException("Empty propertyName.", "propertyName");

            int raisesCount = 0;
            PropertyChangedEventHandler checker
                = (sender, e) =>
                      {
                          if (e.PropertyName == propertyName)
                          {
                              raisesCount++;
                          }
                      };

            viewModel.PropertyChanged += checker;
            try
            {
                method(viewModel);
            }
            finally
            {
                viewModel.PropertyChanged -= checker;
            }

            if (raisesCount != expectedRaisesCount)
            {
                throw new AssertionException(string.Format(
                    "Property '{0}': expected {1} raise, but was {2}.", 
                    propertyName, 
                    expectedRaisesCount,
                    raisesCount));
            }
        }
    }
}